package com.example.xmpic.ui.activity.setting;

import android.graphics.Bitmap;
import android.graphics.Paint;
import android.os.Message;
import androidx.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;

import com.example.common.base.BaseBindActivity;
import com.example.common.base.OnCallBackToRefresh;
import com.example.common.utils.InputFilterUtil;
import com.example.xmpic.R;
import com.example.xmpic.databinding.ActivitySettingInfoBinding;
import com.example.xmpic.support.FunError;
import com.example.xmpic.support.FunSupport;
import com.example.xmpic.support.OnFunDeviceOptListener;
import com.example.xmpic.support.config.JsonConfig;
import com.example.xmpic.support.config.OPTimeQuery;
import com.example.xmpic.support.config.OPTimeSetting;
import com.example.xmpic.support.config.StatusNetInfo;
import com.example.xmpic.support.config.SystemInfo;
import com.example.xmpic.support.models.FunDevice;
import com.example.xmpic.support.models.FunLoginType;
import com.example.xmpic.support.utils.UIFactory;
import com.example.xmpic.view.BaseTipsDialog;
import com.lib.EDEV_JSON_ID;
import com.lib.EUIMSG;
import com.lib.FunSDK;
import com.lib.IFunSDKResult;
import com.lib.MsgContent;
import com.lib.sdk.bean.DefaultConfigBean;
import com.lib.sdk.bean.HandleConfigData;
import com.lib.sdk.struct.H264_DVR_FILE_DATA;


import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * @author skygge
 * @date 2019-10-21.
 * GitHub：javofxu@github.com
 * email：skygge@yeah.net
 * description：摄像头关于设备页面
 */
public class CameraSetInfoActivity extends BaseBindActivity<ActivitySettingInfoBinding> implements OnFunDeviceOptListener,IFunSDKResult {
    private FunDevice mFunDevice;
    private Bitmap mQrCodeBmp = null;
    private DefaultConfigBean mDefault = null;
    private int mHandler;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_setting_info;
    }

    @Override
    protected void initialize() {
        super.initialize();
        int id = getIntent().getIntExtra("FUN_DEVICE_ID", 0);
        mFunDevice = FunSupport.getInstance().findDeviceById(id);
        if ( null == mFunDevice ) {
            finish();
        }
    }

    @Override
    protected void initView() {
        super.initView();
        mDefault = new DefaultConfigBean();
        mHandler = FunSDK.RegUser(this);
        mDBind.time.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG);
        mDBind.time.getPaint().setAntiAlias(true);
        mDBind.sn.getCheckedView().setImageResource(R.drawable.icon_copy_sel);
    }

    @Override
    protected void initData() {
        super.initData();
        requestSystemInfo();
        Calendar calendar = Calendar.getInstance(Locale.getDefault());
        float zoneOffset = (float) calendar.get(java.util.Calendar.ZONE_OFFSET);
        float zone = (float) (zoneOffset / 60.0 / 60.0 / 1000.0);// 时区，东时区数字为正，西时区为负
        if (zone>0){
            mDBind.timeZone.setDetailText(getString(R.string.east) + zone);
        }else {
            mDBind.timeZone.setDetailText(getString(R.string.west) + zone);
        }
    }

    @Override
    protected void initListener() {
        super.initListener();
        FunSupport.getInstance().registerOnFunDeviceOptListener(this);
        mDBind.ivCommonBack.setOnClickListener(view -> finish());
        mDBind.reset.setOnClickListener(view -> resetDevice());
        mDBind.restart.setOnClickListener(v -> restartDevice());
        mDBind.time.setOnClickListener(v -> syncDeviceTime());
        mDBind.sn.getCheckedView().setOnClickListener(v -> {
            boolean success = InputFilterUtil.copy(mContext,mDBind.sn.getDetailText());
            if (success){
                showToast(getString(R.string.success_copy));
            }
        });
    }

    //同步设备时间（这个时间同步 设备端如果开启了NTP服务器同步的话，
    // 这个设置是不起作通的，因为设备会到服务器那边同步时间，
    // 所以这个时候只需要同步时区就可以了）
    private void syncDevTime(String sysTime) {
        OPTimeSetting devTimeInfo = (OPTimeSetting)mFunDevice.checkConfig(OPTimeSetting.CONFIG_NAME);
        devTimeInfo.setmSysTime(sysTime);
        FunSupport.getInstance().requestDeviceSetConfig(mFunDevice, devTimeInfo);
    }

    //同步设备时区
    private void syncDevZone(Calendar calendar) {
        if (calendar == null) {
            return;
        }
        float zoneOffset = (float) calendar.get(java.util.Calendar.ZONE_OFFSET);
        float zone = (float) (zoneOffset / 60.0 / 60.0 / 1000.0);// 时区，东时区数字为正，西时区为负
        FunSupport.getInstance().requestSyncDevZone(mFunDevice, (int) (-zone * 60));
    }

    /**
     * 请求获取系统信息:SystemInfo/Status.NatInfo
     */
    private void requestSystemInfo() {
        // 获取系统信息
        FunSupport.getInstance().requestDeviceConfig(mFunDevice, SystemInfo.CONFIG_NAME);
        // 获取NAT状态
        FunSupport.getInstance().requestDeviceConfig(mFunDevice, StatusNetInfo.CONFIG_NAME);

        FunSupport.getInstance().requestDeviceCmdGeneral(mFunDevice, new OPTimeQuery());
    }

    private void refreshSystemInfo() {
        if ( null != mFunDevice ) {
            SystemInfo systemInfo = (SystemInfo)mFunDevice.getConfig(SystemInfo.CONFIG_NAME);
            if ( null != systemInfo ) {
                // 序列号
                mDBind.sn.setDetailText(systemInfo.getSerialNo());

                // 设备型号
                mDBind.type.setDetailText(systemInfo.getHardware());

                // 软件版本号
                mDBind.softwareVersion.setDetailText(systemInfo.getSoftwareVersion());

                // 发布时间
                mDBind.releaseTime.setDetailText(systemInfo.getBuildTime());

                // 获取发布状态
                getReleaseEdition(systemInfo.getSoftwareVersion(), systemInfo.getBuildTime());

                // 设备连接方式
                mDBind.netType.setDetailText(getResources().getString(getConnectTypeStringId(mFunDevice.getNetConnectType())));

                // 生成二维码
                Bitmap qrCodeBmp = UIFactory.createCode(systemInfo.getSerialNo(), 600, 0xff202020);
                if ( null != qrCodeBmp ) {
                    if ( null != mQrCodeBmp ) {
                        mQrCodeBmp.recycle();
                    }
                    mQrCodeBmp = qrCodeBmp;
                    mDBind.imgDeviceQRCode.setImageBitmap(qrCodeBmp);
                }
            }

            StatusNetInfo netInfo = (StatusNetInfo)mFunDevice.getConfig(StatusNetInfo.CONFIG_NAME);
            if ( null != netInfo ) {
                if("Conneted".equals(netInfo.getNatStatus())){
                    mDBind.netStatus.setDetailText(getResources().getString(R.string.connected));
                }else{
                    mDBind.netStatus.setDetailText(getResources().getString(R.string.unconnected));
                }
            }
        }
    }

    private void refreshTime() {
        if (null != mFunDevice ) {
            OPTimeQuery mQuery = (OPTimeQuery) mFunDevice.getConfig(OPTimeQuery.CONFIG_NAME);
            if (null != mQuery) {
                String mOPTimeQuery = mQuery.getOPTimeQuery();
                mDBind.time.setText(mOPTimeQuery);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
                try {
                    Date date = sdf.parse(mOPTimeQuery);
                    mDBind.time.setDevSysTime(date.getTime());
                    mDBind.time.onStartTimer();
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 0: p2p 1:转发 2IP直连
    private int getConnectTypeStringId(int netConnectType) {
        if ( netConnectType == 0 ) {
            return R.string.device_net_connect_type_p2p;
        } else if ( netConnectType == 1 ) {
            return R.string.device_net_connect_type_transmit;
        } else if ( netConnectType == 2 ) {
            return R.string.device_net_connect_type_ip;
        } else if ( netConnectType == 5) {
            return R.string.device_net_connect_type_rps;
        }

        return R.string.device_net_connect_type_unknown;
    }

    @Override
    public void onDeviceLoginSuccess(FunDevice funDevice) {

    }

    @Override
    public void onDeviceLoginFailed(FunDevice funDevice, Integer errCode) {

    }

    @Override
    public void onDeviceGetConfigSuccess(FunDevice funDevice, String configName, int nSeq) {
        if (null != mFunDevice && funDevice.getId() == mFunDevice.getId()
                && (SystemInfo.CONFIG_NAME.equals(configName)
                || StatusNetInfo.CONFIG_NAME.equals(configName))) {
            dismissProgressDialog();
            refreshSystemInfo();
        }
        if(OPTimeQuery.CONFIG_NAME.equals(configName)){
            refreshTime();
        }
    }

    @Override
    public void onDeviceGetConfigFailed(FunDevice funDevice, Integer errCode) {
        dismissProgressDialog();
        showToast(FunError.getErrorStr(errCode));
    }

    @Override
    public void onDeviceSetConfigSuccess(FunDevice funDevice, String configName) {
        if (OPTimeSetting.CONFIG_NAME.equals(configName) ) {
           dismissProgressDialog();
            // 重新获取时间
            showToast(getString(R.string.synchronous_completion));
            FunSupport.getInstance().requestDeviceCmdGeneral(mFunDevice, new OPTimeQuery());
        }
    }

    @Override
    public void onDeviceSetConfigFailed(FunDevice funDevice, String configName, Integer errCode) {
        showToast(FunError.getErrorStr(errCode));
    }

    @Override
    public void onDeviceChangeInfoSuccess(FunDevice funDevice) {

    }

    @Override
    public void onDeviceChangeInfoFailed(FunDevice funDevice, Integer errCode) {

    }

    @Override
    public void onDeviceOptionSuccess(FunDevice funDevice, String option) {

    }

    @Override
    public void onDeviceOptionFailed(FunDevice funDevice, String option, Integer errCode) {

    }

    @Override
    public void onDeviceFileListChanged(FunDevice funDevice) {

    }

    @Override
    public void onDeviceFileListChanged(FunDevice funDevice, H264_DVR_FILE_DATA[] datas) {

    }

    @Override
    public void onDeviceFileListGetFailed(FunDevice funDevice) {

    }

    @Override
    public int OnFunSDKResult(Message msg, MsgContent msgContent) {
        dismissProgressDialog();
        if (msg.what == EUIMSG.DEV_SET_JSON) {
            if (msg.arg1 < 0) {
                showToast(FunError.getErrorStr(msg.arg1));
            } else {
                if (msgContent.str.equals(JsonConfig.OPERATION_DEFAULT_CONFIG)) {
                    JSONObject object = new JSONObject();
                    try {
                        object.put("Action", "Reboot");
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    FunSDK.DevCmdGeneral(mHandler, mFunDevice.devSn, EDEV_JSON_ID.OPMACHINE, JsonConfig.OPERATION_MACHINE, 1024, 5000,
                            HandleConfigData.getSendData(JsonConfig.OPERATION_MACHINE, "0x1", object).getBytes(), -1, 0);
                    showToast(getString(R.string.device_system_info_defaultconfigsucc));
                }
            }
        }
        return 0;
    }

    private void resetDevice() {
        BaseTipsDialog mDialog = new BaseTipsDialog(mContext, new OnCallBackToRefresh() {
            @Override
            public void onConfirm() {
                showProgressDialog();
                mDefault.setAllConfig(1);
                FunSDK.DevSetConfigByJson(mHandler, mFunDevice.devSn, JsonConfig.OPERATION_DEFAULT_CONFIG,
                        HandleConfigData.getSendData(JsonConfig.OPERATION_DEFAULT_CONFIG, "0x1", mDefault),
                        -1, 20000, mFunDevice.getId());
            }

            @Override
            public void onCancel() {

            }
        });
        mDialog.setMsg(getString(R.string.reset_to_default_set) + "?");
        mDialog.show();
    }

    private void restartDevice(){
        BaseTipsDialog mDialog = new BaseTipsDialog(mContext, new OnCallBackToRefresh() {
            @Override
            public void onConfirm() {
                JSONObject object = new JSONObject();
                try {
                    object.put("Action", "Reboot");
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                FunSDK.DevCmdGeneral(mHandler, mFunDevice.devSn, EDEV_JSON_ID.OPMACHINE, JsonConfig.OPERATION_MACHINE, 1024, 5000,
                        HandleConfigData.getSendData(JsonConfig.OPERATION_MACHINE, "0x1", object).getBytes(), -1, 0);
                showToast(getString(R.string.wait));
            }

            @Override
            public void onCancel() {

            }
        });
        mDialog.setMsg(getString(R.string.are_you_sure_want_to_restart_the_device));
        mDialog.show();
    }

    private void syncDeviceTime(){
        BaseTipsDialog mDialog = new BaseTipsDialog(mContext, new OnCallBackToRefresh() {
            @Override
            public void onConfirm() {
                if (FunSupport.getInstance().getLoginType() == FunLoginType.LOGIN_BY_AP ||
                        FunSupport.getInstance().getLoginType() == FunLoginType.LOGIN_BY_LOCAL) {
                    showProgressDialog();
                    Calendar cal = Calendar.getInstance(Locale.getDefault());
                    String sysTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(cal.getTime());
                    syncDevZone(cal);
                    syncDevTime(sysTime);
                } else {
                    showToast(getString(R.string.device_time_in_AP_or_local_mode));
                }
            }

            @Override
            public void onCancel() {

            }
        });
        mDialog.setTitleAndButton(getString(R.string.sync_ipc_time), getString(R.string.cancel), getString(R.string.ok));
        mDialog.show();
    }

    private void getReleaseEdition(String softVersion, String releaseDate){
        String devId = getReleaseDevTid(softVersion);
        OkHttpClient okHttpClient = new OkHttpClient();
        MediaType JSON = MediaType.parse("application/json; charset=utf-8");
        JSONObject json = new JSONObject();
        try {
            json.put("devId", devId);
            json.put("releaseDate", releaseDate);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        RequestBody requestBody = RequestBody.create(JSON, String.valueOf(json));
        Request request = new Request.Builder()
                .url("https://sw.xm030.cn/soft/api/infoVersionView/findRelease")
                .addHeader("application/json","Content-Type").post(requestBody)
                .build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                try {
                    assert response.body() != null;
                    JSONObject json= new JSONObject(response.body().string());
                    JSONObject json2 = json.getJSONObject("data");
                    boolean release = json2.getBoolean("release");
                    Log.i(TAG,""+release);
                    runOnUiThread(() -> mDBind.releaseStatus.setDetailText(release ? "Release" : "Beta"));
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public String getReleaseDevTid(String softVersion){
        String devId = "";
        String[] array = softVersion.split("\\.");
        if (array.length >= 7) {
            StringBuilder devID = new StringBuilder();
            for (int i =3; i< array.length; i++) {
                devID.append(array[i]);
            }
            if (!TextUtils.isEmpty(devID.toString())) {
                devId = replaceDevID(devID.toString());
            }
        }
        return devId;
    }

    public String replaceDevID(String devId){
        if (devId.length() <20) {
            return devId;
        }
        String str5 = devId.substring(5,6);
        StringBuilder de = new StringBuilder(devId);
        if (Integer.parseInt(str5)< 5) {
            de.replace(8,19,"XXXXXXXXXXX");
        }else{
            de.replace(8,17,"XXXXX0000");
        }
        return de.toString();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if ( null != mQrCodeBmp ) {
            mQrCodeBmp.recycle();
            mQrCodeBmp = null;
        }
        FunSupport.getInstance().removeOnFunDeviceOptListener(this);
    }
}
